package com.dyj.common.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.exceptions.ForestRuntimeException;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.http.ForestResponse;
import com.dtflys.forest.interceptor.Interceptor;
import com.dyj.common.client.AuthClient;
import com.dyj.common.config.AgentConfiguration;
import com.dyj.common.domain.ClientTokenInfo;
import com.dyj.common.domain.query.BaseTransactionMerchantQuery;
import com.dyj.common.domain.query.ClientTokenQuery;
import com.dyj.common.domain.vo.ClientTokenVo;
import com.dyj.common.domain.vo.TpThirdV2TokenVo;
import com.dyj.common.enums.TransactionMerchantTokenTypeEnum;
import com.dyj.common.service.IAgentTokenService;
import com.dyj.common.utils.DyConfigUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 交易进件接口token拦截器
 */
@Component
public class TransactionMerchantTokenInterceptor implements Interceptor<Object> {

    private final Log log = LogFactory.getLog(TransactionMerchantTokenInterceptor.class);
    @Resource
    private AuthClient authClient;

    @Override
    public boolean beforeExecute(ForestRequest request) {
        Integer tenantId = null;
        String clientKey = "";
        TransactionMerchantTokenTypeEnum transactionMerchantTokenTypeEnum = null;
        Object[] arguments = request.getArguments();
        for (Object argument : arguments == null ? new Object[0] : arguments) {
            if (argument instanceof BaseTransactionMerchantQuery) {
                BaseTransactionMerchantQuery query = (BaseTransactionMerchantQuery) argument;
                tenantId = query.getTenantId();
                clientKey = query.getClientKey();
                transactionMerchantTokenTypeEnum = query.getTransactionMerchantTokenType();
            }
        }
        if (TransactionMerchantTokenTypeEnum.TP_THIRD_V2_TOKEN.equals(transactionMerchantTokenTypeEnum)){
            //处理服务商token
            TpThirdV2TokenVo tpThirdV2Token = DyConfigUtils.getAgentTokenService().getTpThirdV2Token(tenantId, clientKey);
            if (Objects.isNull(tpThirdV2Token)) {
                AgentConfiguration agent = DyConfigUtils.getAgent(tenantId, clientKey);
                tpThirdV2Token = authClient.tpThirdV2Token(agent.getClientKey(), agent.getClientSecret(), agent.getTicket());
                if (Objects.nonNull(tpThirdV2Token) && StringUtils.hasLength(tpThirdV2Token.getComponent_access_token())) {
                    DyConfigUtils.getAgentTokenService().setTpThirdV2Token(tenantId, clientKey, tpThirdV2Token);
                }
            }

            if (Objects.isNull(tpThirdV2Token)) {
                throw new RuntimeException("component_access_token is null");
            }
            request.addHeader("access-token", tpThirdV2Token.getComponent_access_token());
        }else {
            //处理非服务商获取token
            IAgentTokenService agentTokenService = DyConfigUtils.getAgentTokenService();
            ClientTokenInfo clientTokenInfo = agentTokenService.getClientTokenInfo(tenantId, clientKey);
            if (Objects.isNull(clientTokenInfo)) {
                AgentConfiguration agent = DyConfigUtils.getAgent(tenantId, clientKey);
                ClientTokenQuery clientTokenQuery = new ClientTokenQuery();
                clientTokenQuery.setClient_key(agent.getClientKey());
                clientTokenQuery.setClient_secret(agent.getClientSecret());
                ClientTokenVo clientToken = authClient.getClientToken(clientTokenQuery).getData();
                if (Objects.nonNull(clientToken) && clientToken.getError_code() == 0) {
                    clientTokenInfo = agentTokenService.setClientTokenInfo(tenantId, clientKey, clientToken.getAccess_token(), clientToken.getExpires_in());
                }
            }
            if (Objects.nonNull(clientTokenInfo)) {
                request.addHeader("access-token", clientTokenInfo.getAccessToken());
            }
        }
        return true;
    }

    @Override
    public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) {
        StringBuilder sb = new StringBuilder("TransactionTokenInterceptor onError ");
        sb.append("url:");
        sb.append(request.getUrl());
        sb.append(", ");
        sb.append("params:");
        sb.append(JSONObject.toJSONString(request.getArguments()));
        sb.append(", ");
        sb.append("result:");
        sb.append(response.getContent());
        sb.append(", ");
        sb.append("msg:");
        sb.append(ex.getMessage());
        log.info(sb.toString());
    }

}
